﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace IslandInterloper.Engine
{
    public static class Result
    {
        #region Framework
        public enum ResultValue
        {
            Success,
            Failure
        }
        private const ResultValue DefaultResultValue = ResultValue.Failure;
        private static XElement CreateGenericResult(ResultValue theResultValue)
        {
            return new XElement(GameXNames.root, new XElement(GameXNames.result, theResultValue), new XElement(GameXNames.payload));
        }
        private static bool ValidateResult(XElement root,out ResultValue theResultValue)
        {
            theResultValue = DefaultResultValue;
            return (root.Name.LocalName == GameXNames.root && root.Element(GameXNames.result) != null && root.Element(GameXNames.payload) != null && Enum.TryParse<ResultValue>(root.Element(GameXNames.result).Value, out theResultValue));
        }
        private static bool ValidateResult(XElement root)
        {
            ResultValue theResultValue;
            return ValidateResult(root, out theResultValue);
        }
        private static XElement GetPayload(XElement root,out ResultValue theResultValue)
        {
            if (ValidateResult(root,out theResultValue))
            {
                return root.Element(GameXNames.payload);
            }
            else
            {
                return null;
            }
        }
        private static XElement GetPayload(XElement root)
        {
            ResultValue theResultValue = DefaultResultValue;
            return GetPayload(root, out theResultValue);
        }
        #endregion
        #region Generic Messages
        internal static XElement CreateGenericSuccessResult()
        {
            return CreateGenericResult(ResultValue.Success);
        }
        internal static XElement CreateGenericFailureResult(string theFailureReason)
        {
            XElement result = CreateGenericResult(ResultValue.Failure);
            result.Element(GameXNames.payload).Add(new XElement(GameXNames.failureReason,theFailureReason));
            return result;
        }
        public static ResultValue GetResult(XElement root, out bool success)
        {
            ResultValue result = DefaultResultValue;
            success = ValidateResult(root, out result);
            return result;
        }
        public static ResultValue GetResult(XElement root)
        {
            bool success = false;
            return GetResult(root, out success);
        }
        public static string GetFailureReason(XElement root, out bool success)
        {
            XElement payload = GetPayload(root);
            success = false;
            if (payload != null)
            {
                return Payload.GetString(payload, GameXNames.failureReason, out success, string.Empty);
            }
            else
            {
                return string.Empty;
            }
        }
        public static string GetFailureReason(XElement root)
        {
            bool success = false;
            return GetFailureReason(root, out success);
        }
        #endregion
        #region Avatar Information
        internal static XElement CreateAvatarInformationResult(Avatar theAvatar)
        {
            Config theConfig = theAvatar.Game.Config;
            Commodities theCommodities = theAvatar.Game.Commodities;
            XElement result = CreateGenericSuccessResult();
            GetPayload(result).Add(
                new XElement(GameXNames.state, theAvatar.State));
            if (theAvatar.State != AvatarState.Uninitialized)
            {
                GetPayload(result).Add(
                    new XElement(GameXNames.dockedIsland, theAvatar.DockedIslandID),
                    new XElement(GameXNames.day, theAvatar.Day),
                    new XElement(GameXNames.speed, theAvatar.Speed.ToString()),
                    new XElement(GameXNames.direction, theConfig.FormatHeading(theAvatar.Direction, true)),
                    new XElement(GameXNames.boundFor, theAvatar.BoundForIslandID.ToString()),
                    new XElement(GameXNames.ship, theAvatar.Ship)
                    );
                if (theAvatar.Inventory != null)
                {
                    XElement inventory = new XElement(GameXNames.commodities);
                    foreach (string commodity in theAvatar.Inventory.Keys)
                    {
                        if (!theCommodities[commodity].Hidden)
                        {
                            inventory.Add(new XElement(commodity,
                                new XElement(GameXNames.units, theAvatar.Inventory[commodity].Units),
                                new XElement(GameXNames.costPerUnit, theAvatar.Inventory[commodity].CostPerUnit),
                                new XElement(GameXNames.tonnage, theAvatar.Inventory[commodity].Tonnage)
                                ));
                        }
                    }
                    GetPayload(result).Add(inventory);
                    GetPayload(result).Add(new XElement(GameXNames.totalTonnage, theAvatar.Inventory.TotalTonnage));
                }
                if (theAvatar.Crew != null)
                {
                    XElement crew = new XElement(GameXNames.crew);
                    Dictionary<string, double> consumptions = new Dictionary<string, double>();
                    foreach (string crewmember in theAvatar.Crew.Keys)
                    {
                        int count = theAvatar.Crew[crewmember].Count;
                        if (count > 0)
                        {
                            crew.Add(new XElement(crewmember,count.ToString()));
                        }
                        foreach (string commodity in theAvatar.Game.Crewmembers[crewmember].DailyConsumptions)
                        {
                            if (!consumptions.ContainsKey(commodity))
                            {
                                consumptions.Add(commodity, theAvatar.Game.Crewmembers[crewmember].GetDailyConsumptionAmount(commodity));
                            }
                            else
                            {
                                consumptions[commodity] += theAvatar.Game.Crewmembers[crewmember].GetDailyConsumptionAmount(commodity);
                            }
                        }
                    }
                    GetPayload(result).Add(crew);
                }
            }
            return result;
        }
        public static AvatarState GetState(XElement root, out bool success)
        {
            return Payload.GetEnum<AvatarState>(GetPayload(root), GameXNames.state, out success, AvatarState.Uninitialized);
        }
        public static AvatarState GetState(XElement root)
        {
            bool success;
            return GetState(root, out success);
        }
        public static string GetSpeed(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.speed, out success, string.Empty);
        }
        public static string GetSpeed(XElement root)
        {
            bool success = false;
            return GetSpeed(root, out success);
        }
        public static int GetDockedIsland(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.dockedIsland, out success, -1);
        }
        public static int GetDockedIsland(XElement root)
        {
            bool success;
            return GetDockedIsland(root, out success);
        }
        public static int GetBoundFor(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.boundFor, out success, -1);
        }
        public static int GetBoundFor(XElement root)
        {
            bool success;
            return GetBoundFor(root, out success);
        }
        public static int GetDay(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.day, out success, -1);
        }
        public static int GetDay(XElement root)
        {
            bool success = false;
            return GetDay(root, out success);
        }
        public static double GetTotalTonnage(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.totalTonnage, out success, 0.0);
        }
        public static double GetTotalTonnage(XElement root)
        {
            bool success = false;
            return GetTotalTonnage(root, out success);
        }
        public static string GetShip(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.ship, out success, string.Empty);
        }
        public static string GetShip(XElement root)
        {
            bool success;
            return GetShip(root, out success);
        }
        public static string[] GetInventoryCommodities(XElement root, out bool success)
        {
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.commodities);
                if (inventory != null)
                {
                    return Utilities.ChildXElementsToStringArray(inventory, out success);
                }
            }
            return new List<string>().ToArray();
        }
        public static string[] GetInventoryCommodities(XElement root)
        {
            bool success;
            return GetInventoryCommodities(root, out success);
        }
        private static double GetInventoryDoubleValue(XElement root, string commodity, string theXName, out bool success, double theDefault)
        {
            double result = theDefault;
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.commodities);
                if (inventory != null)
                {
                    XElement element = inventory.Element(commodity);
                    if (element != null)
                    {
                        result = Utilities.XElementToDouble(element.Element(theXName));
                        success = true;
                    }
                }
            }
            return result;
        }
        public static double GetInventoryUnits(XElement root, string commodity, out bool success)
        {
            return GetInventoryDoubleValue(root, commodity, GameXNames.units, out success, 0.0);
        }
        public static double GetInventoryUnits(XElement root, string commodity)
        {
            bool success;
            return GetInventoryUnits(root, commodity, out success);
        }
        public static double GetInventoryCostPerUnit(XElement root, string commodity, out bool success)
        {
            return GetInventoryDoubleValue(root, commodity, GameXNames.costPerUnit, out success, 0.0);
        }
        public static double GetInventoryCostPerUnit(XElement root, string commodity)
        {
            bool success;
            return GetInventoryCostPerUnit(root, commodity, out success);
        }
        public static double GetInventoryTonnage(XElement root, string commodity, out bool success)
        {
            return GetInventoryDoubleValue(root, commodity, GameXNames.tonnage, out success, 0.0);
        }
        public static double GetInventoryTonnage(XElement root, string commodity)
        {
            bool success;
            return GetInventoryTonnage(root, commodity, out success);
        }
        public static string[] GetCrewList(XElement root, out bool success)
        {

            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement crew = payload.Element(GameXNames.crew);
                if (crew != null)
                {
                    return Utilities.ChildXElementsToStringArray(crew, out success);
                }
            }
            return new List<string>().ToArray();
        }
        public static string[] GetCrewList(XElement root)
        {
            bool success;
            return GetCrewList(root, out success);
        }
        public static int GetCrewCount(XElement root, string crewmember, out bool success)
        {
            success = true;
            return Utilities.XElementToInt(GetPayload(root).Element(GameXNames.crew).Element(crewmember));
        }
        public static int GetCrewCount(XElement root, string crewmember)
        {
            bool success;
            return GetCrewCount(root, crewmember, out success);
        }
        #endregion
        #region Avatar Speed List
        internal static XElement CreateAvatarSpeedListResult(AvatarSpeeds theAvatarSpeeds)
        {
            XElement result = CreateGenericSuccessResult();
            foreach (string speed in theAvatarSpeeds.Keys)
            {
                GetPayload(result).Add(new XElement(speed));
            }
            return result;
        }
        public static string[] GetAvatarSpeedList(XElement root, out bool success)
        {
            List<string> result = new List<string>();
            foreach (XElement element in GetPayload(root).Elements())
            {
                result.Add(element.Name.LocalName);
            }
            success = true;
            return result.ToArray();
        }
        public static string[] GetAvatarSpeedList(XElement root)
        {
            bool success;
            return GetAvatarSpeedList(root, out success);
        }
        #endregion
        #region Avatar Speed Information
        internal static XElement CreateAvatarSpeedInformationResult(AvatarSpeed theAvatarSpeed)
        {
            XElement result = CreateGenericSuccessResult();
            GetPayload(result).Add(
                new XElement(GameXNames.name, theAvatarSpeed.Name),
                new XElement(GameXNames.factor, theAvatarSpeed.Factor)
                );
            return result;
        }
        public static string GetString(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.name, out success, string.Empty);
        }
        public static string GetString(XElement root)
        {
            bool success;
            return GetString(root, out success);
        }
        public static double GetDouble(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.factor, out success, 0.0);
        }
        public static double GetDouble(XElement root)
        {
            bool success;
            return GetDouble(root, out success);
        }
        #endregion
        #region Ship Information
        internal static XElement CreateShipInformationResult(Ship theShip)
        {
            XElement result = CreateGenericSuccessResult();
            GetPayload(result).Add(
                new XElement(GameXNames.name,theShip.Name),
                new XElement(GameXNames.maximumSpeed,theShip.MaximumSpeed),
                new XElement(GameXNames.maximumTonnage,theShip.MaximumTonnage),
                new XElement(GameXNames.sailingDifficulty,theShip.SailingDifficulty)
                );
            return result;
        }
        public static double GetMaximumSpeed(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.maximumSpeed, out success, 0.0);
        }
        public static double GetMaximumSpeed(XElement root)
        {
            bool success;
            return GetMaximumSpeed(root, out success);
        }
        public static double GetMaximumTonnage(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.maximumTonnage, out success, 0.0);
        }
        public static double GetMaximumTonnage(XElement root)
        {
            bool success;
            return GetMaximumTonnage(root, out success);
        }
        public static double GetSailingDifficulty(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.sailingDifficulty, out success, 0.0);
        }
        public static double GetSailingDifficulty(XElement root)
        {
            bool success;
            return GetSailingDifficulty(root, out success);
        }
        #endregion
        #region Island Information
        internal static XElement CreateIslandInformationResult(Island theIsland, AvatarIsland theAvatarIsland, Config theConfig, Avatar theAvatar)
        {
            XElement result;
            if (theAvatarIsland != null)
            {
                result = CreateGenericSuccessResult();
                Location islandPosition = new Location(theIsland.Position.X - theAvatar.Position.X, theIsland.Position.Y - theAvatar.Position.Y);
                GetPayload(result).Add(
                    new XElement(GameXNames.bookmarked, theAvatarIsland.BookMarked),
                    new XElement(GameXNames.notes, theAvatarIsland.Notes),
                    new XElement(GameXNames.located, true),
                    new XElement(GameXNames.dayLocated, theAvatarIsland.DayLocated),
                    new XElement(GameXNames.visited, theAvatarIsland.Visited),
                    new XElement(GameXNames.name, (theAvatarIsland.Visited) ? (theIsland.Name) : (theConfig.UnknownIslandName)),
                    islandPosition.ToXElement(GameXNames.position),
                    new XElement(GameXNames.heading, theConfig.FormatHeading(islandPosition.ToHeading(), true))
                    );
                if (theAvatarIsland.Visited)
                {
                    GetPayload(result).Add(
                        new XElement(GameXNames.dayFirstVisited, theAvatarIsland.DayFirstVisited),
                        new XElement(GameXNames.dayLastVisited, theAvatarIsland.DayLastVisited),
                        new XElement(GameXNames.visitCount, theAvatarIsland.VisitCount)
                        );
                    XElement islandCommodities = new XElement(GameXNames.islandCommodities);
                    foreach (string commodity in theIsland.Commodities.Keys)
                    {
                        if (!theAvatar.Game.Commodities[commodity].Hidden)
                        {
                            islandCommodities.Add(new XElement(commodity,
                                new XElement(GameXNames.buyUnitPrice, theIsland.Commodities[commodity].BuyUnitPrice),
                                new XElement(GameXNames.sellUnitPrice, theIsland.Commodities[commodity].SellUnitPrice),
                                new XElement(GameXNames.maximumPurchase, theAvatar.Inventory[commodity].MaximumPurchase(theIsland.Commodities[commodity].BuyUnitPrice))
                                ));
                        }
                    }
                    GetPayload(result).Add(islandCommodities);
                }
            }
            else if (theIsland != null)
            {
                result = CreateGenericSuccessResult();
                GetPayload(result).Add(
                    new XElement(GameXNames.located, false),
                    new XElement(GameXNames.name, (theConfig.UnknownIslandName))
                    );
            }
            else
            {
                result = CreateGenericFailureResult("No such island.");
            }
            return result;
        }
        public static bool GetBookmarked(XElement root, out bool success)
        {
            return Payload.GetBool(GetPayload(root), GameXNames.bookmarked, out success, false);
        }
        public static bool GetBookmarked(XElement root)
        {
            bool success = false;
            return GetBookmarked(root, out success);
        }
        public static bool GetLocated(XElement root, out bool success)
        {
            return Payload.GetBool(GetPayload(root), GameXNames.located, out success, false);
        }
        public static bool GetLocated(XElement root)
        {
            bool success = false;
            return GetLocated(root, out success);
        }
        public static bool GetVisited(XElement root, out bool success)
        {
            return Payload.GetBool(GetPayload(root), GameXNames.visited, out success, false);
        }
        public static bool GetVisited(XElement root)
        {
            bool success = false;
            return GetVisited(root, out success);
        }
        public static int GetDayFirstVisited(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.dayFirstVisited, out success, -1);
        }
        public static int GetDayFirstVisited(XElement root)
        {
            bool success = false;
            return GetDayFirstVisited(root, out success);
        }
        public static int GetDayLastVisited(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.dayLastVisited, out success, -1);
        }
        public static int GetDayLastVisited(XElement root)
        {
            bool success = false;
            return GetDayLastVisited(root, out success);
        }
        public static int GetDayLocated(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.dayLocated, out success, -1);
        }
        public static int GetDayLocated(XElement root)
        {
            bool success = false;
            return GetDayLocated(root, out success);
        }
        public static int GetVisitCount(XElement root, out bool success)
        {
            return Payload.GetInt(GetPayload(root), GameXNames.visitCount, out success, -1);
        }
        public static int GetVisitCount(XElement root)
        {
            bool success = false;
            return GetVisitCount(root, out success);
        }
        public static string GetIslandName(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.name, out success, string.Empty);
        }
        public static string GetIslandName(XElement root)
        {
            bool success = false;
            return GetIslandName(root, out success);
        }
        public static string GetNotes(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.notes, out success, string.Empty);
        }
        public static string GetNotes(XElement root)
        {
            bool success = false;
            return GetNotes(root, out success);
        }
        public static ILocation GetIslandPosition(XElement root, out bool success)
        {
            return Payload.GetLocation(GetPayload(root), GameXNames.position, out success);
        }
        public static ILocation GetIslandPosition(XElement root)
        {
            bool success = false;
            return GetIslandPosition(root, out success);
        }
        public static string GetIslandHeading(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.heading, out success, string.Empty);
        }
        public static string GetIslandHeading(XElement root)
        {
            bool success = false;
            return GetIslandHeading(root, out success);
        }
        public static string GetHeading(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.direction, out success, string.Empty);
        }
        public static string GetHeading(XElement root)
        {
            bool success = false;
            return GetHeading(root, out success);
        }
        public static string[] GetIslandCommodities(XElement root, out bool success)
        {
            List<string> result = new List<string>();
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.islandCommodities);
                if (inventory != null)
                {
                    foreach (XElement element in inventory.Elements())
                    {
                        result.Add(element.Name.LocalName);
                    }
                }
            }
            return result.ToArray();
        }
        public static string[] GetIslandCommodities(XElement root)
        {
            bool success;
            return GetIslandCommodities(root, out success);
        }
        public static double GetIslandCommodityBuyUnitPrice(XElement root, string commodity, out bool success)
        {
            double result = 0.0;
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.islandCommodities);
                if (inventory != null)
                {
                    XElement element = inventory.Element(commodity);
                    if (element != null)
                    {
                        result = Utilities.XElementToDouble(element.Element(GameXNames.buyUnitPrice));
                        success = true;
                    }
                }
            }
            return result;
        }
        public static double GetIslandCommodityBuyUnitPrice(XElement root, string commodity)
        {
            bool success;
            return GetIslandCommodityBuyUnitPrice(root, commodity, out success);
        }
        public static double GetIslandCommoditySellUnitPrice(XElement root, string commodity, out bool success)
        {
            double result = 0.0;
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.islandCommodities);
                if (inventory != null)
                {
                    XElement element = inventory.Element(commodity);
                    if (element != null)
                    {
                        result = Utilities.XElementToDouble(element.Element(GameXNames.sellUnitPrice));
                        success = true;
                    }
                }
            }
            return result;
        }
        public static double GetIslandCommoditySellUnitPrice(XElement root, string commodity)
        {
            bool success;
            return GetIslandCommodityBuyUnitPrice(root, commodity, out success);
        }
        public static double GetIslandCommodityMaximumPurchase(XElement root, string commodity, out bool success)
        {
            double result = 0.0;
            success = false;
            XElement payload = GetPayload(root);
            if (payload != null)
            {
                XElement inventory = payload.Element(GameXNames.islandCommodities);
                if (inventory != null)
                {
                    XElement element = inventory.Element(commodity);
                    if (element != null)
                    {
                        result = Utilities.XElementToDouble(element.Element(GameXNames.maximumPurchase));
                        success = true;
                    }
                }
            }
            return result;
        }
        public static double GetIslandCommodityMaximumPurchase(XElement root, string commodity)
        {
            bool success;
            return GetIslandCommodityMaximumPurchase(root, commodity, out success);
        }
        #endregion
        #region Island Lists
        internal static XElement CreateIslandListResult(int[] theIslandList)
        {
            XElement result = CreateGenericSuccessResult();
            XElement islandList = new XElement(GameXNames.islandList);
            foreach (int islandId in theIslandList)
            {
                islandList.Add(new XElement(GameXNames.islandId, islandId));
            }
            GetPayload(result).Add(islandList);
            return result;
        }
        public static int[] GetIslandList(XElement root, out bool success)
        {
            success = false;
            List<int> result = new List<int>();
            if (GetPayload(root) == null) return result.ToArray();
            if (GetPayload(root).Element(GameXNames.islandList) == null) return result.ToArray();
            foreach (XElement element in GetPayload(root).Element(GameXNames.islandList).Elements(GameXNames.islandId))
            {
                int islandId;
                success = int.TryParse(element.Value, out islandId);
                if (!success)
                {
                    result.Clear();
                    break;
                }
                result.Add(islandId);
            }
            return result.ToArray();
        }
        public static int[] GetIslandList(XElement root)
        {
            bool success = false;
            return GetIslandList(root, out success);
        }
        #endregion
        #region Commodity Information
        internal static XElement CreateCommodityInformationResult(Commodity commodity)
        {
            XElement result = CreateGenericSuccessResult();
            GetPayload(result).Add(new XElement(GameXNames.name, commodity.Name),
                new XElement(GameXNames.basePrice, commodity.BasePrice),
                new XElement(GameXNames.tonsPerUnit, commodity.TonsPerUnit),
                new XElement(GameXNames.traded, commodity.Traded));
            return result;
        }
        public static string GetName(XElement root, out bool success)
        {
            return Payload.GetString(GetPayload(root), GameXNames.name, out success, string.Empty);
        }
        public static string GetName(XElement root)
        {
            bool success;
            return GetName(root, out success);
        }
        public static double GetBasePrice(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.basePrice, out success, 0.0);
        }
        public static double GetBasePrice(XElement root)
        {
            bool success;
            return GetBasePrice(root, out success);
        }
        public static double GetTonsPerUnit(XElement root, out bool success)
        {
            return Payload.GetDouble(GetPayload(root), GameXNames.tonsPerUnit, out success, 0.0);
        }
        public static double GetTonsPerUnit(XElement root)
        {
            bool success;
            return GetTonsPerUnit(root, out success);
        }
        public static bool GetTraded(XElement root, out bool success)
        {
            return Payload.GetBool(GetPayload(root), GameXNames.traded, out success, false);
        }
        public static bool GetTraded(XElement root)
        {
            bool success;
            return GetTraded(root, out success);
        }
        #endregion
        #region Crewmember Information
        internal static XElement CreateCrewmemberInformationResult(Crewmember theCrewmember)
        {
            XElement result = CreateGenericSuccessResult();
            XElement dailyConsumptions = new XElement(GameXNames.dailyConsumptions);
            foreach (string dailyConsumption in theCrewmember.DailyConsumptions)
            {
                dailyConsumptions.Add(new XElement(dailyConsumption), theCrewmember.GetDailyConsumptionAmount(dailyConsumption));
            }
            GetPayload(result).Add(new XElement(GameXNames.name, theCrewmember.Name),
                dailyConsumptions
                );
            return result;
        }
        public static string[] GetDailyConsumptions(XElement root, out bool success)
        {
            List<string> result = new List<string>();
            success = true;
            foreach (XElement element in GetPayload(root).Element(GameXNames.dailyConsumptions).Elements())
            {
                result.Add(element.Name.LocalName);
            }
            return result.ToArray();
        }
        public static string[] GetDailyConsumptions(XElement root)
        {
            bool success;
            return GetDailyConsumptions(root, out success);
        }
        public static double GetDailyConsumptionAmount(XElement root, string commodity, out bool success)
        {
            double result = 0;
            success = true;
            result = Utilities.XElementToDouble(GetPayload(root).Element(GameXNames.dailyConsumptions).Element(commodity));
            return result;
        }
        public static double GetDailyConsumptionAmount(XElement root, string commodity)
        {
            bool success;
            return GetDailyConsumptionAmount(root, commodity, out success);
        }
        #endregion
    }
}
